#include	"CenterApp.h"
#include	"network/CenterService.h"
#include	"network/Database.h"
#include	"network/ZoneConnector.h"
#include	"core/Cache.h"

#include	<DateTime.h>
#include	<IniFile.h>
#include	<Path.h>
#include	<Script.h>

bool CenterApp::OnInit(Command & cmd) {
	IniFile conf;
	if (!conf.Load("config.ini")) throw std::runtime_error("failed to load config.ini");

	int log_level = conf.Get<int>("center", "log_level", ELog::Info);
	Logger::Instance().Init("center", "logs", 4194304, (ELog::Level)log_level);

	std::string redis_ip = conf.Get<std::string>("redis", "ip", "127.0.0.1");
	int redis_port = conf.Get<int>("redis", "port", 6379);
	if (!GCache.Initialize(redis_ip, redis_port)) {
		LOG_ERR("Failed to connect to Redis[%s:%d]", redis_ip.c_str(), redis_port);
		return false;
	}

	std::string zone_ip = conf.Get<std::string>("zone", "ip", "127.0.0.1");
	int zone_port = conf.Get<int>("zone", "port", 10000);
	int status = GZone.Connect(zone_ip, zone_port);
	if (status != ENet::Success) {
		LOG_ERR("Failed to connect to zone[%s:%d]. Code : %d", zone_ip.c_str(), zone_port, status);
		return false;
	}

	std::string dbproxy_ip = conf.Get<std::string>("dbproxy", "ip", "127.0.0.1");
	int dbproxy_port = conf.Get<int>("dbproxy", "port", 10001);
	status = GDatabase.Connect(dbproxy_ip, dbproxy_port);
	if (status != ENet::Success) {
		LOG_ERR("Failed to connect to dbproxy[%s:%d]. Code : %d", dbproxy_ip.c_str(), dbproxy_port, status);
		return false;
	}

	std::string center_ip = conf.Get<std::string>("center", "ip", "127.0.0.1");
	int center_port = conf.Get<int>("center", "port", 10003);
	status = GService.Listen(center_ip, center_port);
	if (status != ENet::Success) {
		LOG_ERR("Failed to listen on[%s:%d]. Code : %d", center_ip.c_str(), center_port, status);
		return false;
	}

	extern void RegisterLuaApi_File();
	extern void RegisterLuaApi_Misc();
	extern void RegisterLuaApi_Net();
	RegisterLuaApi_File();
	RegisterLuaApi_Misc();
	RegisterLuaApi_Net();

	Path::Traverse("scripts/center", [](const std::string & file) {
		if (file.size() <= 4) return;
		std::string ext = ToUpper(file.substr(file.size() - 4));
		if (ext == ".LUA") GLua.DoFile(file, true);
	});

	GLua.Call("Scheduler", "Start");
	LockFPS(50);
	LOG_INFO("Application center started ....");
	return true;
}

void CenterApp::OnBreath() {
	GCache.Breath();

	GLua.Call("Timer", "Trigger");

	static int last_hms = 0;
	DateTime now;
	int hms = now.nHour * 10000 + now.nMin * 100 + now.nSec;
	if (last_hms != hms) {
		last_hms = hms;
		GLua.Call("Scheduler", "TimePoint", hms);
	}
}

void CenterApp::OnExit(int code) {
	LOG_INFO("Application center will exit : %d", code);
}

RUN_APP(CenterApp)